package com.demo.filter;

import org.apache.commons.io.IOUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;


/**
 * @author wangfengchen
 * <p>
 * 包装HttpServletRequest
 * CustomRequestWrapper + RequestReplaceFilter 的作用是：
 * 解决异常处理器中拿post请求的json参数时，报request流只能读一次的错
 * 原因是 request.getReader() 和 request.getInputStream() 都是只能调用一次
 * 所以我这里要使用 HttpServletRequestWrapper 来实现自定义的 CustomRequestWrapper 包装类
 * 把request里的 body 保存在 CustomRequestWrapper 中, 并且重写 getInputStream()方法
 * 然后所有的request都在 RequestReplaceFilter 中被转换成了我自定义的HttpServletRequestWrapper
 * 然后获取 body时就都是调用 CustomRequestWrapper 中的 getBody()方法了
 */
public class CustomRequestWrapper extends HttpServletRequestWrapper {

  private final byte[] body;

  public byte[] getBody() {
    return body;
  }

  public CustomRequestWrapper(HttpServletRequest request) throws IOException {
    super(request);
    body = IOUtils.toByteArray(super.getInputStream());
  }

  @Override
  public BufferedReader getReader() throws IOException {
    return new BufferedReader(new InputStreamReader(getInputStream()));
  }

  @Override
  public ServletInputStream getInputStream() throws IOException {
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
    return new ServletInputStream() {

      @Override
      public int read() throws IOException {
        return byteArrayInputStream.read();
      }

      @Override
      public void setReadListener(ReadListener listener) {
      }

      @Override
      public boolean isReady() {
        return false;
      }

      @Override
      public boolean isFinished() {
        return false;
      }
    };
  }


}